package com.example.common.advice;


import com.alibaba.fastjson.JSONObject;
import com.example.common.utils.R;
import com.example.common.utils.AesUtil;
import com.example.common.utils.JwtUtil;
import com.example.sys.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Slf4j
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {

    @Value("${config.encrypt.enable}")
    private boolean encrypt;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        try {
            Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            User user = new User();
            BeanUtils.copyProperties(principal, user);
            String token = JwtUtil.generateToken(user.getUsername());
            redisTemplate.opsForValue().set(token, JSONObject.toJSONString(user),120, TimeUnit.MINUTES);
            response.getHeaders().add("Access-Control-Expose-Headers", "token");
            response.getHeaders().add("token", AesUtil.encrypt(token));
            if(encrypt) {
                log.info("加密前数据：{}", JSONObject.toJSONString(body));
            }
            log.info("加密后数据：{}", AesUtil.encrypt(body));
            return AesUtil.encrypt(body);
        }catch (Exception e) {
            log.error("响应拦截处理错误：{}", e);
            return R.error("服务器错误");
        }
    }
}
